#pragma once 
/*
    单个缓冲区设计
*/

#include<iostream>
#include<vector>
#include<assert.h>
#define BUFFER_DEFAULT_SIZE (1*1024*1024)
#define BUFFER_INCREMENT_SIZE (1*1024*1024)
#define BUFFER_THRESHOLD_SIZE (10*1024*1024)
namespace zxlog{
    class Buffer{
        public:
            Buffer():_reader_idx(0),_writer_idx(0),_v(BUFFER_DEFAULT_SIZE){}
            bool empty(){return _reader_idx == _writer_idx;}//判断缓冲区是否为空         
            size_t readAbleSize(){return _writer_idx - _reader_idx;}//判断缓冲区可写大小
            size_t writerAbleSize(){return _v.size()-_writer_idx;}//判断可读位置大小
            void reset(){_reader_idx = _writer_idx = 0;}//重置缓冲区（清空缓冲区）
            void swap(Buffer& buf)//交换两个缓冲区
            {
                _v.swap(buf._v);
                std::swap(_reader_idx,buf._reader_idx);
                std::swap(_writer_idx,buf._writer_idx);
            }
            void push(const char* data,size_t len)//向缓冲区中写入数据
            {
                //assert(len <= writerAbleSize());
                ensureEnoughSpace(len);
                std::copy(data,data+len,&_v[_writer_idx]);
                moveWriter(len);
            }
            const char*  begin()//返回可读的起始位置
            {
                return &_v[_reader_idx];
            }
            void pop(size_t len)//向缓冲区中读取数据
            {
                assert(_reader_idx <= _writer_idx);
                _reader_idx += len;
            }
            void moveReader(size_t len)
            {
                assert(len + _reader_idx <= readAbleSize());
                _reader_idx += len;
            }
            void moveWriter(size_t len)
            {
                assert(len <= writerAbleSize());
                _writer_idx += len;
            }
        private:
            void ensureEnoughSpace(size_t len)
            {
                if(len <= writerAbleSize())return;
                size_t new_capacity = 0;
                if(_v.size() < BUFFER_THRESHOLD_SIZE)
                {
                    new_capacity = _v.size()*2 + len;
                }else
                {
                    new_capacity = _v.size()+BUFFER_INCREMENT_SIZE+len;
                }
                _v.resize(new_capacity);
            }
        private:
           size_t _reader_idx;//写位置
           size_t _writer_idx;//读位置
           std::vector<char> _v;//缓冲区
    };
}
